Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patches from Photon OS #1428

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

bhllamoreaux
Copy link
Contributor

These two patches are logically separate but are based on recent fixes for bugs I encountered recently in Photon OS. I think they can also be applicable to upstream kpatch.

The changes are:

  1. Using the dynamically read prefix symbol size instead of hardcoding to 16 (fixes cases with non-standard padding for __cfi)
  2. Refactor definitions of callback structs in kpatch-patch.h to compile with the correct input type for the callback function. Fixes a "bad function cast" gcc error that I ran into, which occurs during the final livepatch module compilation.

In commit [1], kpatch added support for function padding,
and CONFIG_CFI_CLANG, which hardcoded a value of 16 for
the prefix size.

In some cases, the padding around __cfi prefixed functions can
vary. For example, in Photon OS 5.0, the __cfi prefix
size is modified in a patch for the gcc RAP plugin [2].

Since we have read the prefix size anyways, we can use it
instead of hardcoding.

Ref:
1. dynup@3e54c63
2. https://github.com/vmware/photon/blob/5.0/SPECS/linux/secure/gcc-rap-plugin-with-kcfi.patch

Signed-off-by: Brennan Lamoreaux <[email protected]>
Livepatch callbacks are packed into specific sections
by gcc by the macros defined in kpatch-macros.h. Callbacks
take the form of:

    struct example {
        type *(fn)(struct klp_object *obj);
        char* objname;
    }

However, create-diff-objects.c can't include the kernel livepatch
header because it is compiled separately from the kernel module.
So the solution before was to define the structs in the header file as:

    struct example {
                type *(fn)(void *obj);
                char* objname;
        }

and then cast fn to (type *(fn)(struct klp_object *obj)) if necessary.
This way, the same header file and definitions can be used in
both places.

But! If compiled with the right GCC flags, such as -Wbad-function-cast,
this casting may throw an error during livepatch building, which is what
I am seeing (not sure why, since it was always fine before...).

Solution: Define the callback function parameter as the correct type, which
allows us to get rid of the troublesome casting.

Since we need to know if callbacks are present in kpatch-patch.h, we can move
the definition of HAVE_CALLBACKS to from livepatch-patch-hook.c to kpatch-patch.h.

IMPORTANT: For correctness, this change requires proper ordering of include
statements! kpatch-patch.h must always be included AFTER linux/livepatch.h
(if using linux/livepatch.h).

Signed-off-by: Brennan Lamoreaux <[email protected]>
@joe-lawrence
Copy link
Contributor

Hi @bhllamoreaux, thanks for posting.

(1) The symbol prefix change looks good.

(2) Hmm, the old kpatch-patch-hook.c file was to support legacy, pre-livepatch-support kernels. I suppose the only valid use case today would be a modern kernel with !CONFIG_LIVEPATCH ... for which I don't think we really want/need to support in kpatch-build anymore. Let me think a bit more on this as maybe we just finally rip out that old code and simplify this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants